using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Linq.Expressions;
using BaseBL;
using Northwinddemo.DAL.EntityClasses;
using Northwinddemo.BusinessLayer.Models.ViewModels;
using Northwinddemo.BusinessLayer.Repository.Abstract;
using Northwinddemo.BusinessLayer.Models;
using xVal.ServerSide;
using MvcContrib;
using Northwinddemo.BusinessLayer;

namespace Northwinddemo.Web.Controllers
{
    public class ProductsController : ControllerEx
    {
        private IProductsRepository productsRepository;
        private ISuppliersRepository suppliersRepository;
        private ICategoriesRepository categoriesRepository;
        private IAdapterFactory adapterFactory;

        public ProductsController(IProductsRepository productsRepository,
                                  ISuppliersRepository suppliersRepository,
                                  ICategoriesRepository categoriesRepository,
                                  IAdapterFactory adapterFactory)
        {
            this.productsRepository = productsRepository;
            this.suppliersRepository = suppliersRepository;
            this.categoriesRepository = categoriesRepository;
            this.adapterFactory = adapterFactory;
        }


        //
        // GET: /Products/
        
        public ActionResult Index(int? page, string search)
        {
            var productsViewModel = GetProductsViewModel(page, search);
            return Request.IsAjaxRequest() ? View("Grid", productsViewModel) : View(productsViewModel);
        }

        //
        // GET: /Products/Grid

        public ActionResult Grid(int? page, string search)
        {
            var productsViewModel = GetProductsViewModel(page, search);
            return View(productsViewModel);
        }

        private ProductsViewModel GetProductsViewModel(int? page, string search)
        {
            var products = productsRepository.GetBySearchOrderByProductNamePrefetchSupplierAndCategory(search, page);
            return new ProductsViewModel(products, search);
        }

        //
        // GET: /Products/Details/<productId>

        public ActionResult Details(int id)
        {
            var product = productsRepository.GetById(id);
            if (product.SupplierId.HasValue)
            {
                NorthwinddemoHelper.SetSupplierToViewData(product.SupplierId.Value, 
                    ViewData, suppliersRepository);
                NorthwinddemoHelper.SetCategoryToViewData(product.CategoryId.Value,
                    ViewData, categoriesRepository);
            }
            return View(new ProductViewModel(product));
        }

        //
        // GET: /Products/Edit/5
 
        public ActionResult Edit(int id)
        {
            var product = id != 0 ? productsRepository.GetById(id) : GetNewProduct();
            var productViewModel = new ProductViewModel(product);
            SetSuppliersToViewData();
            SetCategoriesToViewData();
            return View(productViewModel); 
        }

        //
        // POST: /Products/Edit/5

        [HttpPost]
        public ActionResult Edit(int id, FormCollection collection)
        {
            var product = id != 0 ? productsRepository.GetById(id) : GetNewProduct();
            var productViewModel = new ProductViewModel(product);
            try
            {
                UpdateModel(productViewModel, collection.ToValueProvider());
                productsRepository.Save(productViewModel.Product);
            }
            catch (RulesException ex)
            {
                ex.CopyToModelState(ModelState, ExpressHelper.GetPropertyName<ProductViewModel>(p => p.Product));
            }
            if (ModelState.IsValid)
            {
                return RedirectToAction("Details", "Products", new { id = product.ProductId });
            }
            else
            {
                SetSuppliersToViewData();
                SetCategoriesToViewData();
                return View(productViewModel);
            }
        }

        private void SetSuppliersToViewData()
        {
            NorthwinddemoHelper.SetSuppliersToViewData(ViewData, suppliersRepository);
        }

        private void SetCategoriesToViewData()
        {
            NorthwinddemoHelper.SetCategoriesToViewData(ViewData, categoriesRepository);
        }

        private ProductsEntity GetNewProduct()
        {
            return new ProductsEntity();
        }

    }
}
